package com.example.algorithm.symbol;

import org.w3c.dom.Node;

/**
 * @program: algorithm
 * @description: 符号表
 * @packagename: com.example.algorithm.symbol
 * @author: Jay
 * @date: 2022/04/27 16:49:04
 **/
public class SymbolTable<Key,Value>{

    //记录首结点
    private Node head;

    //记录符号表元素的个数
    private int N;

    public class Node{
        //键
        public Key key;
        //值
        public Value value;
        //下一个结点
        public Node next;

        public Node(Key key, Value value, Node next){
            this.key = key;
            this.value = value;
            this.next = next;
        }

    }

    public SymbolTable(){
        this.head = new Node(null, null, null);
        this.N = 0;
    }

    //获取符号表个数
    public int size(){
        return N;
    }

    //往符号表中插入键值对
    public void put(Key key, Value value){

        //符号表中已经存在已经存在键为key的键值对，只要找到该节点，替换值为value即可
        Node n = head;
        while (n.next!=null){
            //变化n
            n = n.next;
            //判断n节点的键是否是key，是则替换
            if (n.key.equals(key)){
                n.value = value;
                return;
            }
        }
        //如果符号表中不存在键为key的键值对，只要创建新的节点，保存要插入的键值对，把新的节点插入到链表的头部，head.next = 新节点即可
        Node newNode = new Node(key, value, null);
        Node oldFirst = head.next;
        newNode.next = oldFirst;
        head.next = newNode;

        N++;
    }

    //删除符号表键为key的键值对
    public void delete(Key key){
        //找到键为key的结点，把该结点从列表中删除
        Node n = head;
        while (n.next != null){
            //判断n结点的下一个结点的键是否为key，如果是就删除该结点
            if (n.next.key.equals(key)){
                n.next = n.next.next;
                N--;
                return;
            }
            n = n.next;
        }
    }

    //从符号表中获取key对应的值
    public Value get(Key key){

        Node n = head;
        while (n.next != null){
             n = n.next;
             if (n.key.equals(key)){
                 return n.value;
             }
        }
        return null;
    }


}
